package com.jyszkj.map.util

import com.blankj.utilcode.util.ConvertUtils
import com.jyszkj.map.view.OsmdroidMapView
import org.osmdroid.util.BoundingBox
import org.osmdroid.util.GeoPoint
import org.osmdroid.views.MapView
import kotlin.math.cos
import kotlin.math.ln
import kotlin.math.min

object CircleZoomCalculator {
    /**
     * 计算并设置完美显示圆形的zoom级别
     * @param mapView 地图视图
     * @param center 圆心位置
     * @param radiusMeters 圆的半径(米)
     * @param paddingPx 边缘留白像素数
     */
    fun setPerfectZoomForCircle(mapView: OsmdroidMapView, center: GeoPoint,
                                radiusMeters: Double, paddingHeight: Int = 0,paddingPx: Int = 100) {
        // 1. 计算圆形的最小边界框
        val circleBBox = calculateCircleBoundingBox(center, radiusMeters)

        // 2. 计算完美zoom级别
        val zoom = calculatePerfectZoom(mapView, circleBBox, paddingHeight, paddingPx)

        // 3. 设置地图视图
        mapView.setZoom(zoom)
        mapView.controller.setCenter(center)
    }

    /**
     * 计算并设置完美显示圆形的zoom级别
     * @param mapView 地图视图
     * @param center 圆心位置
     * @param radiusMeters 圆的半径(米)
     * @param paddingPx 边缘留白像素数
     */
    fun setPerfectDeviceZoomForCircle(mapView: OsmdroidMapView, center: GeoPoint,
                                      radiusMeters: Double, paddingHeight: Int = 0, paddingPx: Int = 100, offsetZoom: Int) {
        // 1. 计算圆形的最小边界框
        val circleBBox = calculateCircleBoundingBox(center, radiusMeters)

        // 2. 计算完美zoom级别
        val zoom = calculatePerfectZoom(mapView, circleBBox, paddingHeight, paddingPx)

        // 3. 设置地图视图
        mapView.setZoom(zoom - offsetZoom)
        mapView.controller.setCenter(center)
    }

    /**
     * 计算圆形的最小边界框
     */
    private fun calculateCircleBoundingBox(center: GeoPoint, radius: Double): BoundingBox {
        // 地球半径(米)
        val earthRadius = 6378137.0

        // 计算纬度偏移(弧度)
        val latOffset = radius / earthRadius
        val north = center.latitude + Math.toDegrees(latOffset)
        val south = center.latitude - Math.toDegrees(latOffset)

        // 计算经度偏移(考虑纬度影响)
        val lonOffset = radius / (earthRadius * cos(Math.toRadians(center.latitude)))
        val east = center.longitude + Math.toDegrees(lonOffset)
        val west = center.longitude - Math.toDegrees(lonOffset)

        return BoundingBox(north, east, south, west)
    }

    /**
     * 计算完美zoom级别
     */
    private fun calculatePerfectZoom(mapView: MapView, bbox: BoundingBox,paddingHeight: Int,
                                     paddingPx: Int): Double {
        // 获取地图视图尺寸(考虑padding)
        val mapWidth = mapView.width - 2 * paddingPx
        val mapHeight = (mapView.height - paddingHeight) - 2 * paddingPx

        // 计算经度和纬度跨度
        val lonSpan = bbox.lonEast - bbox.lonWest
        val latSpan = bbox.latNorth - bbox.latSouth

        // 计算基于宽度和高度的zoom级别
        val zoomX = log2(360.0 / lonSpan * mapWidth / 256.0)
        val zoomY = log2(180.0 / latSpan * mapHeight / 256.0)

        // 取较小的zoom级别以确保完全显示
        return min(zoomX, zoomY).coerceIn(mapView.minZoomLevel, mapView.maxZoomLevel)
    }

    private fun log2(x: Double): Double = ln(x) / ln(2.0)
}